package com.tepth.remote.core.net.soap;

import android.content.Context;

import com.tencent.bugly.crashreport.BuglyLog;
import com.tencent.bugly.crashreport.CrashReport;
import com.tepth.remote.core.app.ConfigKeys;
import com.tepth.remote.core.app.Control;
import com.tepth.remote.core.net.CommonParams;
import com.tepth.remote.core.net.HttpMethod;
import com.tepth.remote.core.net.callback.IError;
import com.tepth.remote.core.net.callback.IFailure;
import com.tepth.remote.core.net.callback.IRequest;
import com.tepth.remote.core.net.callback.ISoapSuccess;
import com.tepth.remote.core.net.callback.SoapCallback;
import com.tepth.remote.core.net.loader.ControlLoader;
import com.tepth.remote.core.net.loader.LoaderStyle;
import com.tepth.remote.core.utils.thread.ControlSingleThread;
import com.tepth.remote.core.utils.thread.RunnableCallback;

import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import org.xmlpull.v1.XmlPullParserException;

import java.io.IOException;
import java.util.WeakHashMap;

/**
 * Description:Soap连接类
 *
 * @author Hequn.Lee
 * @date 2018/11/8
 */
public class SoapClient {
    /**
     * 请求参数
     */
    private final WeakHashMap<String, Object> PARAMS;
    /**
     * 命名空间
     */
    private final String NAMESPACE;
    /**
     * 请求方法名
     */
    private final String METHOD;
    /**
     * 请求回调
     */
    private final IRequest REQUEST;
    /**
     * 请求成功回调
     */
    private final ISoapSuccess SUCCESS;
    /**
     * 请求失败回调
     */
    private final IFailure FAILURE;
    /**
     * 网络错误回调
     */
    private final IError ERROR;
    /**
     * 上下文
     */
    private final Context CONTEXT;
    /**
     * 菊花样式
     */
    private final LoaderStyle LOADERSTYLE;

    SoapClient(WeakHashMap<String, Object> params,
               String nameSpace,
               String method,
               IRequest request,
               ISoapSuccess success,
               IFailure failure,
               IError error,
               Context context,
               LoaderStyle loaderStyle) {
        this.PARAMS = params;
        this.NAMESPACE = nameSpace;
        this.METHOD = method;
        this.REQUEST = request;
        this.SUCCESS = success;
        this.FAILURE = failure;
        this.ERROR = error;
        this.CONTEXT = context;
        this.LOADERSTYLE = loaderStyle;
    }

    /**
     * 创建Soap连接构造类
     *
     * @return Soap连接构造类
     */
    public static SoapClientBuilder builder() {
        return new SoapClientBuilder();
    }

    /**
     * 封装请求参数
     *
     * @param method 请求方法枚举
     * @throws IOException            IO异常
     * @throws XmlPullParserException XML读写异常
     */
    private void packageParameter(HttpMethod method) throws IOException, XmlPullParserException {
        if (REQUEST != null) {
            //请求开始的回调
            REQUEST.onRequestStart();
        }
        //显示菊花
        if (LOADERSTYLE != null && CONTEXT != null) {
            ControlLoader.showLoading(CONTEXT, LOADERSTYLE);
        }
        final SoapObject soap = new SoapObject(NAMESPACE, METHOD);
        // 设置WebService提交的数据集
        if (PARAMS != null && !PARAMS.isEmpty()) {
            for (WeakHashMap.Entry<String, Object> entry : PARAMS.entrySet()) {
                soap.addProperty(entry.getKey(), entry.getValue());
            }
        }
        switch (method) {
            case POST:
                post(soap);
                break;
            case UPLOAD:
                upload(soap);
                break;
            default:
                break;
        }
    }

    /**
     * 进行POST请求
     *
     * @param soap 封装好的请求SoapObject
     * @throws IOException            IO异常
     * @throws XmlPullParserException XML读写异常
     */
    private void post(SoapObject soap) throws IOException, XmlPullParserException {
        final String baseUrl = Control.getConfiguration(ConfigKeys.SOAP_HOST);
        // 初始化数据请求
        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
                SoapEnvelope.VER11);
        envelope.dotNet = true;
        envelope.bodyOut = soap;
        envelope.setOutputSoapObject(soap);
        // 发起Web请求
        HttpTransportSE http = new HttpTransportSE(baseUrl + "/WebServices/GpsServiceNew.asmx", CommonParams.HTTP_TIME_OUT);
        http.debug = CommonParams.DEBUG;
        http.call(NAMESPACE + METHOD, envelope);
        // 获取Web请求结果， 数据需要从 result.getProperty(0) 获取
        SoapObject result = (SoapObject) envelope.bodyIn;
        //回调方法
        SoapCallback.getInstance().callback(result, REQUEST, SUCCESS, FAILURE, LOADERSTYLE);
    }

    /**
     * 进行UPLOAD请求
     *
     * @param soap 封装好的请求SoapObject
     * @throws IOException            IO异常
     * @throws XmlPullParserException XML读写异常
     */
    private void upload(SoapObject soap) throws IOException, XmlPullParserException {
        final String baseUrl = Control.getConfiguration(ConfigKeys.RETROFIT_HOST);
        // 初始化数据请求
        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
                SoapEnvelope.VER11);
        envelope.dotNet = true;
        envelope.bodyOut = soap;
        envelope.setOutputSoapObject(soap);
        // 发起Web请求
        HttpTransportSE http = new HttpTransportSE(baseUrl + "/WebServices/GpsService.asmx", CommonParams.HTTP_TIME_OUT);
        http.debug = CommonParams.DEBUG;
        http.call(NAMESPACE + METHOD, envelope);
        // 获取Web请求结果， 数据需要从 result.getProperty(0) 获取
        SoapObject result = (SoapObject) envelope.bodyIn;
        //回调方法
        SoapCallback.getInstance().callback(result, REQUEST, SUCCESS, FAILURE, LOADERSTYLE);
    }

    /**
     * 发起post请求
     */
    public final void post() {
        ControlSingleThread.getThreadPool().execute(ControlSingleThread
                .getInstance()
                .setCallback(new RunnableCallback() {
                    @Override
                    public void callback() {
                        try {
                            packageParameter(HttpMethod.POST);
                        } catch (Exception e) {
                            BuglyLog.e("SoapException", "====方法名====：" + METHOD);
                            CrashReport.postCatchedException(e);
                            e.printStackTrace();
                            Control.getHandler().post(new Runnable() {
                                @Override
                                public void run() {
                                    if (ERROR != null) {
                                        ERROR.onError(0, "网络连接出错");
                                    }
                                }
                            });
                        }
                    }
                }).getRunnable());
    }

    /**
     * 发起upload请求
     */
    public final void upload() {
        ControlSingleThread.getThreadPool().execute(ControlSingleThread
                .getInstance()
                .setCallback(new RunnableCallback() {
                    @Override
                    public void callback() {
                        try {
                            packageParameter(HttpMethod.UPLOAD);
                        } catch (Exception e) {
                            BuglyLog.e("SoapException", "====方法名====：" + METHOD);
                            CrashReport.postCatchedException(e);
                            e.printStackTrace();
                            Control.getHandler().post(new Runnable() {
                                @Override
                                public void run() {
                                    if (ERROR != null) {
                                        ERROR.onError(0, "网络连接出错");
                                    }
                                }
                            });
                        }
                    }
                }).getRunnable());
    }
}
